/**
 * 
 */
package com.module.osr.stormbringer.view;

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import com.ahq.main.H1HighlightBorder;
import com.dalonedrau.d20.Diceroller;
import com.dalonedrau.jogl.engine.Action;
import com.dalonedrau.jogl.engine.GameApplet;
import com.dalonedrau.jogl.engine.InputEvent;
import com.dalonedrau.jogl.engine.Interactive;
import com.dalonedrau.jogl.opengl.View;
import com.dalonedrau.jogl.opengl.ui.Button;
import com.dalonedrau.jogl.opengl.ui.Label;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.border.FlexibleImageBorder;
import com.dalonedrau.jogl.opengl.ui.border.GradientBackgroundBorder;
import com.dalonedrau.jogl.opengl.ui.panel.CardPanel;
import com.dalonedrau.jogl.opengl.ui.panel.LandscapePagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.opengl.ui.panel.PortraitPagePanel;
import com.dalonedrau.jogl.util.UtilityMethods;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;
import com.module.osr.engine.OSRController;
import com.module.osr.stormbringer.bus.SBCharacter;
import com.module.osr.stormbringer.bus.SBPlayer;
import com.module.osr.ui.stormbringer.charcreator.widgets.AttributesOptions;
import com.module.osr.ui.stormbringer.charcreator.widgets.GenderOptions;
import com.module.osr.ui.stormbringer.charcreator.widgets.NationalityOptions;
import com.module.osr.ui.stormbringer.charcreator.widgets.StepsPanel;
import com.module.osr.ui.stormbringer.charviewer.SBCharacterViewer;
import com.module.stormbringer.globals.Globals;
import com.rpg.base.RPGConsts;

/**
 * @author Donald
 */
public class SBCharCreator implements View {
	/** the one and only instance of the <code>OverworldView</code> class. */
	private static SBCharCreator	instance;
	/**
	 * Gives access to the singleton instance of {@link SBCharCreator}.
	 * @return {@link SBCharCreator}
	 */
	public static SBCharCreator getInstance() {
		if (SBCharCreator.instance == null) {
			SBCharCreator.instance = new SBCharCreator();
		}
		return SBCharCreator.instance;
	}
	private Button				btnBack;
	private Button				btnNext;
	private Label				lblHelper;
	/** the main panel. */
	private Panel				panel;
	/** the panel to re-roll attributes. */
	private AttributesOptions	pnlAttributes;
	/** the title panel. */
	private Panel				pnlButtons;
	/** the gender options panel. */
	private GenderOptions		pnlGender;
	/** the option panel. */
	private CardPanel			pnlOptions;
	/** the steps panel. */
	private StepsPanel			pnlSteps;
	/** the title panel. */
	private PortraitPagePanel	pnlTitle;
	/** flag indicating initialization has been completed. */
	private boolean				runInit	= false;
	/** the current step in the process. */
	private int					step	= 0;
	/** Hidden constructor. */
	private SBCharCreator() {}
	/**
	 * Checks the current step the wizard is on.
	 * @throws Exception if an error occurs
	 */
	private void checkStep() throws Exception {
		pnlSteps.highlightIndex(step);
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		lblHelper.setText("");
		switch (step) {
		case 0:
			break;
		case 1:
			// assign a gender if none assigned yet
			SBCharacter pc = (SBCharacter) Interactive.getInstance().getIO(0);
			int gender = pc.getGender();
			if (pc.getGender() < 0) {
				gender = Diceroller.getInstance().rolldXPlusY(2, -1);
				pc.setSkinTone(RPGConsts.SKIN_01CELT);
				pc.setHeight(RPGConsts.HEIGHT_00AVERAGE);
				pc.setBaseBodyFrame(RPGConsts.BUILD_01MEDIUM);
				pc.setMuscle(RPGConsts.MUSCLE_00AVERAGE);
				pc.setHairStyle(Globals.HAIR_STYLE01);
				pc.setHairColor(Globals.HAIR_COLOR_BRUNETTE);
			}
			pc.setGender(gender);
			pnlGender.setGender(gender);
			pnlOptions.displayChild("gender");
			break;
		case 2:
			pc = (SBCharacter) Interactive.getInstance().getIO(0);
			if (pc.getFullCharisma() <= 0) {
				// roll attributes
				SBPlayer.getInstance().rollFreshHero(pc);
			}
			pnlOptions.displayChild("attributes");
			break;
		case 3:
			pc = (SBCharacter) Interactive.getInstance().getIO(0);
			int race = pc.getRace();
			if (race < 0) {
				// set race
				SBPlayer.getInstance().setFreshHeroRace(pc);
				race = pc.getRace();
				lblHelper.setText(Globals.RACE_DESCRIPTIONS[race]);
			}
			NationalityOptions.getInstance().setRace();
			pnlOptions.displayChild("nationality");
			break;
		}
		sb.returnToPool();
	}
	/**
	 * Creates the title row.
	 * @throws Exception if an error occurs
	 */
	private void createButtonRow() throws Exception {
		pnlButtons = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		btnBack = UIFactory.getInstance().getStandardButton("Back");
		btnBack.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
				InputEvent.getInstance().addAction(
						SBCharCreator.getInstance(), // object
						SBCharCreator.class.getMethod("prevStep", null), 
						null
						);
					//SBCharCreator.getInstance().prevStep();
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		btnBack.setHighlightable(true);
		btnBack.setActive(true);
		btnBack.setHighlightBorder(new H1HighlightBorder());
		pnlButtons.addChild(btnBack);
		pnlButtons.addChild(UIFactory.getInstance().getSpacer(50, 1));
		btnNext = UIFactory.getInstance().getStandardButton("Next");
		btnNext.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					InputEvent.getInstance().addAction(
							SBCharCreator.getInstance(), // object
							SBCharCreator.class.getMethod("nextStep", null), 
							null
							);
					//SBCharCreator.getInstance().nextStep();
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		btnNext.setHighlightable(true);
		btnNext.setActive(true);
		btnNext.setHighlightBorder(new H1HighlightBorder());
		pnlButtons.addChild(btnNext);
		// add border - 16px wide by 13px high
		pnlButtons.setBorder(new FlexibleImageBorder(
				new int[] {
						// bottom-left
						FlexibleImageBorder.BORDER03_BL_LEFT_FULL_BOTTOM_FULL,
						// bottom-right
						FlexibleImageBorder.BORDER07_BR_RIGHT_FULL_BOTTOM_FULL,
						// bottom
						FlexibleImageBorder.BORDER09_B_BOTTOM_FULL,
						// top-left
						FlexibleImageBorder.BORDER10_TL_LEFT_FULL_TOP_HALF,
						// top-right
						FlexibleImageBorder.BORDER14_TR_RIGHT_FULL_TOP_HALF,
						// top
						FlexibleImageBorder.BORDER18_T_TOP_HALF,
						// left
						FlexibleImageBorder.BORDER21_L_LEFT_FULL,
						// right
						FlexibleImageBorder.BORDER23_R_RIGHT_FULL
						}));
	}
	/**
	 * Creates the middle row containing the steps and the character viewer.
	 * @return {@link Panel}
	 * @throws Exception if an error occurs
	 */
	private Panel createMiddleRow() throws Exception {
		// steps on left
		Panel pnl = new LandscapePagePanel(Panel.LANDSCAPE_TOP);
		pnlSteps = new StepsPanel();
		pnl.addChild(pnlSteps);
		// column containing character viewer, options panel
		Panel pnlColumn = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		// 1st row - character viewer
		Panel container1 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		container1.addChild(SBCharacterViewer.getInstance());
		container1.setBorder(new FlexibleImageBorder(
				new int[] {
						// bottom-left
						FlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF,
						// bottom-right
						FlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF,
						// bottom
						FlexibleImageBorder.BORDER08_B_BOTTOM_HALF,
						// top-left
						FlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF,
						// top-right
						FlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF,
						// top
						FlexibleImageBorder.BORDER18_T_TOP_HALF,
						// left
						FlexibleImageBorder.BORDER20_L_LEFT_HALF,
						// right
						FlexibleImageBorder.BORDER22_R_RIGHT_HALF
						}));
		pnlColumn.addChild(container1);
		// 2nd row - options, helper text
		createOptionsPanel();
		Panel container2 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		container2.addChild(pnlOptions);
		lblHelper = UIFactory.getInstance().getStandardH2Label("");
		lblHelper.setMinimumSize(612, 152);
		lblHelper.setMaximumSize(612, 152);
		lblHelper.setVerticalAlignment(Panel.LANDSCAPE_TOP);
		lblHelper.setDebug(true);
		container2.addChild(lblHelper);
		container2.setBorder(new FlexibleImageBorder(
				new int[] {
						// bottom-left
						FlexibleImageBorder.BORDER01_BL_LEFT_HALF_BOTTOM_HALF,
						// bottom-right
						FlexibleImageBorder.BORDER05_BR_RIGHT_HALF_BOTTOM_HALF,
						// bottom
						FlexibleImageBorder.BORDER08_B_BOTTOM_HALF,
						// top-left
						FlexibleImageBorder.BORDER11_TL_LEFT_HALF_TOP_HALF,
						// top-right
						FlexibleImageBorder.BORDER15_TR_RIGHT_HALF_TOP_HALF,
						// top
						FlexibleImageBorder.BORDER18_T_TOP_HALF,
						// left
						FlexibleImageBorder.BORDER20_L_LEFT_HALF,
						// right
						FlexibleImageBorder.BORDER22_R_RIGHT_HALF
						}));
		pnlColumn.addChild(container2);
		pnl.addChild(pnlColumn);
		return pnl;
	}
	/**
	 * Creates the options panel.
	 * @throws Exception if an error occurs
	 */
	private void createOptionsPanel() throws Exception {
		pnlOptions = new CardPanel();
		pnlOptions.addChild("start", new StartOptions());

		pnlGender = new GenderOptions();
		pnlOptions.addChild("gender", pnlGender);

		pnlAttributes = new AttributesOptions();
		pnlOptions.addChild("attributes", pnlAttributes);

		pnlOptions.addChild("nationality", NationalityOptions.getInstance());

		pnlOptions.displayChild("start");
	}
	/**
	 * Creates the title row.
	 * @throws Exception if an error occurs
	 */
	private void createTitleRow() throws Exception {
		pnlTitle = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		Label lbl = UIFactory.getInstance().getStandardH1Label(
				"Create A New Character");
		pnlTitle.addChild(lbl);
		// add border - 16px wide by 13px high
		pnlTitle.setBorder(new FlexibleImageBorder(
				new int[] {
						// bottom-left
						FlexibleImageBorder.BORDER00_BL_LEFT_FULL_BOTTOM_HALF,
						// bottom-right
						FlexibleImageBorder.BORDER04_BR_RIGHT_FULL_BOTTOM_HALF,
						// bottom
						FlexibleImageBorder.BORDER08_B_BOTTOM_HALF,
						// top-left
						FlexibleImageBorder.BORDER13_TL_LEFT_FULL_TOP_FULL,
						// top-right
						FlexibleImageBorder.BORDER17_TR_RIGHT_FULL_TOP_FULL,
						// top
						FlexibleImageBorder.BORDER19_T_TOP_FULL,
						// left
						FlexibleImageBorder.BORDER21_L_LEFT_FULL,
						// right
						FlexibleImageBorder.BORDER23_R_RIGHT_FULL
						}));
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleKeyEvent(final KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_ESCAPE:
			System.out.println("esc");
			GameApplet.getInstance().exit();
			break;
		case KeyEvent.VK_UP:
			break;
		case KeyEvent.VK_DOWN:
			break;
		case KeyEvent.VK_ENTER:
			break;
		case KeyEvent.VK_TAB:
			break;
		case KeyEvent.VK_BACK_SPACE:
			try {} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
			break;
		case KeyEvent.VK_SPACE:
			try {
				// textfield.addCharacter(e.getKeyChar());
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
			break;
		default:
			if (Character.isLetterOrDigit(e.getKeyChar())) {
				try {
					// textfield.addCharacter(e.getKeyChar());
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
			break;
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseOver(final float x, final float y) {
		panel.handleMouseOver(x, y);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMousePress(final MouseEvent e, final float x,
			final float y) {
		panel.handleMouseClick(e, x, y);
	}
	/**
	 * Initializes the {@link View}.
	 * @throws Exception if an error occurs
	 */
	public void init() throws Exception {
		createTitleRow();
		Panel middle = createMiddleRow();
		createButtonRow();
		panel = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		panel.setBorder(new GradientBackgroundBorder());
		panel.addChild(pnlTitle);
		panel.addChild(middle);
		panel.addChild(pnlButtons);
		pnlTitle.setMinimumWidth(panel.getPreferredSize().width);
		((LandscapePagePanel) pnlButtons).setMinimumWidth(
				panel.getPreferredSize().width);
		middle = null;
		Point pt = UtilityMethods.getInstance().centerComponentInFrame(
				panel);
		panel.setPosition(pt.x, pt.y, 0.0f);
		panel.setVisible(true);
		SBCharacter pc = SBPlayer.getInstance().getFreshHero();
		SBCharacterViewer.getInstance().setPc(pc);
		pnlSteps.highlightIndex(step);
		runInit = true;
	}
	public void nextStep() {
		step++;
		try {
			checkStep();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		if (!runInit) {
			try {
				init();
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
		}
		panel.prepareForRendering();
		if (pnlOptions != null) {
			pnlOptions.prepareForRendering();
		}
	}
	public void prevStep() {
		step--;
		if (step < 0) {
			// GO BACK TO MAIN MENU
			step = 0;
		}
		try {
			checkStep();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	public void setHelperText(final String text) {
		lblHelper.setText(text);
	}
	public static final int HELPER_PC_RACE = 0;
	public void setHelperText(final int type) throws Exception {
		SBCharacter pc = (SBCharacter) Interactive.getInstance().getIO(0);
		switch (type) {
		case HELPER_PC_RACE:
			lblHelper.setText(Globals.RACE_DESCRIPTIONS[pc.getRace()]);
			break;
		}
	}
}

/**
 * Start options only has one button.
 * @author Donald
 */
final class StartOptions extends PortraitPagePanel {
	/** Creates a new instance of {@link StartOptions}. */
	StartOptions() {
		super(Panel.PORTRAIT_CENTER);
		super.addChild(UIFactory.getInstance().getSpacer(1, 1));
	}
}
